package com.doroodo.base.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.doroodo.base.dao.BaseDao;
import com.doroodo.base.model.DataGrid;
import com.doroodo.base.service.BaseService;
import com.doroodo.base.service.GenericsUtils;
import com.doroodo.code.util.StringHelper;
import com.doroodo.util.SmarteUntil;

public abstract class BaseServiceImpl<T> implements BaseService<T> {
	
	@Autowired
	protected BaseDao<T> dao;
	
	public BaseDao<T> getDao() {
		return dao;
	}

	private String modalName="";
	
	protected Class<T> entityClass;
	
	protected Class<?> getEntityClass() {
		return entityClass;
	}
	
	public BaseServiceImpl() {
		entityClass = GenericsUtils.getGenericClass(getClass());
		modalName=entityClass.getName();
		modalName=modalName.substring(modalName.lastIndexOf(".")+1);
	}
	
	private String where(String fieldName,String fieldResult,String type) {
		String hql="";
		List<String> whers=SmarteUntil.match(fieldResult, "查询", "条件");
		List<String> vals=SmarteUntil.match(fieldResult, "查询", "值");
		if( (whers.size()>0)&&(whers.size()==vals.size()))
		{
			if("java.lang.integer".equalsIgnoreCase(type)){
				for(int i=0;i<whers.size();i++){
					hql+=" t."+fieldName+" "+whers.get(i)+Integer.parseInt(vals.get(i))+" and";
				}
			}else{
				for(int i=0;i<whers.size();i++){
					hql+=" t."+fieldName+" "+whers.get(i)+"'"+vals.get(i)+"' and";
				}
			}
		}
		return hql;
	}
	
	public Map getHqlByObject(T o){
		String hql = "from "+modalName+" t where";
		Map<String, Object> params = new HashMap<String, Object>();
		for (int i = 0; i < o.getClass().getMethods().length; i++) {
			Method f = o.getClass().getMethods()[i];
			if (f.getName().startsWith("get")
					&& f.getParameterTypes().length == 0 
					&& (!f.getName().equalsIgnoreCase("getClass"))) {
				String fieldResult;
				String fieldName="";
				try {
					fieldResult = f.invoke(o, null) == null ? "" : f.invoke(o, null).toString();
					for (int j = 0; j < o.getClass().getDeclaredFields().length; j++) {
						String fieldName_=o.getClass().getDeclaredFields()[j].getName();
						if(fieldName_.equalsIgnoreCase(f.getName().substring(3))){
							fieldName = fieldName_;
							break;
						}
					}
			
					if( !fieldResult.trim().equals("") && !fieldName.trim().isEmpty()){
						String swhere=where(fieldName,fieldResult,f.getReturnType().getName());
						if(swhere.isEmpty()){
							if("java.lang.integer".equalsIgnoreCase(f.getReturnType().getName())){
								hql+=" t."+fieldName+" = :"+fieldName+" and";
								params.put(fieldName, Integer.parseInt(fieldResult));
							}else{
								hql+=" t."+fieldName+" = :"+fieldName+" and";
								params.put(fieldName, fieldResult);
							}
						}else{
							hql+=swhere;
						}
					}
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		if(hql.endsWith("and")){
			hql = hql.substring(0, hql.length()-3);
		}
		Map<String,Object> m=new HashMap();
		m.put("hql", hql);
		m.put("params", params);
		return m;
	}

	public List<T> get(T o) {
		Map<String,Object> m=getHqlByObject(o);
		List<T> l = dao.find(m.get("hql").toString(),(Map<String, Object>) m.get("params"));
		return l;
	}
	
	

	public DataGrid dataGrid(int page, int rows, String searchName,
			String searchKey) {
		DataGrid dg = new DataGrid();
		String hql = "from "+modalName+" t ";
		Map<String, Object> params = new HashMap<String, Object>();
		if( !searchName.trim().equals("") ){
			hql+="where t."+searchName+" like :key";
			params.put("key", "%%" + searchKey.trim() + "%%");
		}
		String totalHql = "select count(*) " + hql;
		//hql+=" order by t.logDate desc";
		List<T> l=null;
		if(rows==0 &&page==0){
			l = dao.find(hql, params);
		}else{
			l = dao.find(hql, params,page, rows);
		}
		dg.setTotal(dao.count(totalHql, params));
		dg.setRows(l);
		dg.setModelName(StringHelper.uncapitalize(modalName));
		return dg;
	}
	
	public DataGrid dataGrid(int page, int rows, T o) {
		DataGrid dg = new DataGrid();
		Map<String,Object> m=getHqlByObject(o);
		String hql = m.get("hql").toString();
		Map<String, Object> params = (Map<String, Object>) m.get("params");
		String totalHql = "select count(*) " + hql;
		//hql+=" order by t.logDate desc";
		List<T> l=null;
		if(rows==0 &&page==0){
			l = dao.find(hql, params);
		}else{
			l = dao.find(hql, params,page, rows);
		}
		dg.setTotal(dao.count(totalHql, params));
		dg.setRows(l);
		dg.setModelName(StringHelper.uncapitalize(modalName));
		return dg;
	}
	
	public void saveOrUpdate(T o) {
		dao.saveOrUpdate(o);
	}
	
	public void delete(String ids) {
		String[] ids_=ids.split(",");
		for(int i=0;i<ids_.length;i++)
		{
			dao.delete(dao.get((Class<T>) getEntityClass(), Integer.parseInt(ids_[i])));
		}
		
	}

	public List<T> listAll() {
		String hql = "from "+modalName+" t ";
		List<T> l = dao.find(hql);
		return l;
	}
}
